﻿using System;
using System.Data.SQLite;
using System.Linq;
using System.Text;
using Infrastructure.Orm.Extensions;
using Infrastructure.Orm.Contracts;
using Infrastructure.Orm.UnitOfWork.Commands.Interfaces;
using Infrastructure.Orm.UnitOfWork.Mappings;

namespace Infrastructure.Orm.UnitOfWork.Commands.Implementations
{
    internal class UpdateCommand<T> : CommandBuilder<T>, IUpdateCommand
        where T : class, IKeyedPersistent
    {
        private const string Update = "UPDATE";
        private const string Set = " SET ";
        private const string Where = " WHERE[Key] = @Key";
        private static readonly String CommandText;
        static UpdateCommand()
        {
            var commandTextBuilder = new StringBuilder(Update);
            commandTextBuilder.Append(SqlTableName);
            commandTextBuilder.Append(GetColumnValues());
            commandTextBuilder.Append(Where);
            CommandText = commandTextBuilder.ToString();
        }
        private static String GetColumnValues()
        {
            var columns = new StringBuilder(Set);
            ColumnPropertyInfos.Apply(columnPropertyInfo =>
                columns
                .Append(columnPropertyInfo.ToColumnName())
                .Append("=")
                .Append(columnPropertyInfo.ToColumnValue())
                .Append(","));
            columns.RemoveLastChar();
            return columns.ToString();
        }
        private static void AddUpdateParameters(SQLiteCommand command, IKeyedPersistent entity)
        {
            command.Parameters.Clear();
            var parameters = ColumnPropertyInfos.Select(propertyInfo => new SQLiteParameter(propertyInfo.ToColumnValue(), propertyInfo.ToSqLiteObject(entity)));
            command.Parameters.AddRange(parameters.ToArray());
            var key = KeyFactory.Dehidrate(entity.Key);
            command.Parameters.Add(new SQLiteParameter("@Key", key));
        }


        public UpdateCommand()
            : base(CommandText)
        {
        }


        public void Run(SQLiteConnection connection, IKeyedPersistent entity)
        {
            Command.Connection = connection;
            AddUpdateParameters(Command, entity);
            Command.ExecuteNonQuery();
        }
    }
}
